package com.cskaoyan.order.biz.handler;

import com.cskaoyan.mall.commons.exception.BizException;
import com.cskaoyan.mall.commons.exception.ValidateException;
import com.cskaoyan.order.biz.context.AbsTransHandlerContext;
import com.cskaoyan.order.biz.context.CreateOrderContext;
import com.cskaoyan.order.biz.context.TransHandlerContext;
import com.cskaoyan.order.dal.entitys.Item;
import com.cskaoyan.order.dal.entitys.Stock;
import com.cskaoyan.order.dal.persistence.ItemMapper;
import com.cskaoyan.order.dal.persistence.StockMapper;
import com.cskaoyan.order.dto.CartProductDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@Component
public class ValidateHandler extends AbstractTransHandler {
    @Autowired
    ItemMapper itemMapper;
    @Autowired
    StockMapper stockMapper;


    @Override
    public boolean isAsync() {
        return false;
    }

    @Override
    public boolean handle(TransHandlerContext context) {
        /*TODO:参数校验
        *   1、购买的商品有没有下架
        *       1）对应的 stock 为 null
        *       2）Item对象的 status=0
        *   2、 ProductNum 不能超过 限购数量
        *   3、购买的商品是否还有库存
        *   */

        // 让 TransHandlerContext对象context 向下转型为 CreateOrderContext
        CreateOrderContext createOrderContext = (CreateOrderContext) context;
        // List<CartProductDto> cartProductDtoList = createOrderContext.getCartProductDtoList();

        
        /*TODO:1、购买的商品有没有下架
                1）对应的 stock 为 null
                2）Item对象的 status=0*/
        /*在 AbstranctTransPipelineFactory的build方法 中，将 CreateOrderRequest对象
         * 转换为 CreateOrderContext对象 时，并没有给它传入 buyProductIds 的值。
         * 因此这里要给它赋该值*/
        List<CartProductDto> cartProductDtoList = createOrderContext.getCartProductDtoList();

        List<Long> buyProductIds = createOrderContext.getBuyProductIds();

        /*从 cartProductDtoList 中将 购物车中，被选中成为订单中商品 的 id 传给
           buyProductIds */
        // 如果 buyProductIds==null || buyProductIds.size()==0
        if (CollectionUtils.isEmpty(buyProductIds)) {
            // 使用 stream流 遍历 cartProductDtoList ，将里面每个 dto 的 ProductId 都放
            // 到 buyProductIds 里面
            buyProductIds = cartProductDtoList.stream().map(dto -> dto.getProductId()).collect(Collectors.toList());
        }
        // 让 buyProductIds 按 ProductId 从小到大 排序
        buyProductIds.sort(Long::compareTo);
        
        /*TODO:
         *  给 TransHandlerContext对象context 的 buyProductIds 赋值。
         *  原先这里是在后面的 InitOrderHandler 里完成的。我个人进行了修改，
         *  对其进行了提前。
         *  （因为这里正好就有，而且不会对 执行流程 造成影响）*/
        createOrderContext.setBuyProductIds(buyProductIds);

        /*锁定库存 select ... for update 的情况下返回 buyProductIds 中所有 ProductId
         * 的 库存 */
        List<Stock> stocksForUpdateList = stockMapper.findStocksForUpdate(buyProductIds);

        // 如果 stocksForUpdateList==null || stocksForUpdateList.size()==0
        // 说明 tb_stock表 为空，没有数据
        if (CollectionUtils.isEmpty(stocksForUpdateList)) {
            String errorMessage = "对不起(;´༎ຶД༎ຶ`)，您购买的所有商品均已下架！";
            BizException bizException = new BizException();
            bizException.setMessage(errorMessage);
            throw bizException;
        }

        // stocksForUpdateList 的容量应该等于 buyProductIds 的容量
        // 否则说明 tb_stock表 中部分商品未初始化
        if (stocksForUpdateList.size() != buyProductIds.size()) {
            /*不正常（已下架）的 商品 map
            *   key     —— 商品id
            *   value   —— CartProductDto对象*/
            HashMap<Long, CartProductDto> abnormalCartProductDtoMap = new HashMap<>();
            for (CartProductDto cartProductDto : cartProductDtoList) {
                Long productId = cartProductDto.getProductId();
                abnormalCartProductDtoMap.put(productId, cartProductDto);
            }
            // 遍历 stocksForUpdateList
            for (Stock stock : stocksForUpdateList) {
                /*
                * 如果当前 Stock对象stock 非空，且对应的 商品 的 status 不为 0 ，
                * 说明它对应的 商品 正常，将它排除出
                *  不正常（已下架）的商品map<——>abnormalCartProductDtoMap */
                // 当前 Stock对象stock 非空
                if (stock != null) {
                    Long itemId = stock.getItemId();
                    Item item = itemMapper.selectByPrimaryKey(itemId);
                    // 且对应的 商品 的 status 不为 0
                    if (item.getStatus() != 0) {
                        /* 其对应的 商品 正常，将它排除出
                         * 不正常（已下架）的商品map<——>abnormalCartProductDtoMap */
                        abnormalCartProductDtoMap.remove(itemId);
                    }
                }
            }
            // 错误信息
            StringBuffer errorMessage = new StringBuffer("对不起ε(┬┬﹏┬┬)3，您所购买的");
            Set<Long> keySet = abnormalCartProductDtoMap.keySet();
            for (Long itemId : keySet) {
                CartProductDto cartProductDto = abnormalCartProductDtoMap.get(itemId);
                String productName = cartProductDto.getProductName();
                errorMessage.append(" <商品" + productName + "> 和");
            }
            // 去掉最后的 和 字
            errorMessage.deleteCharAt(errorMessage.length() - 1);
            errorMessage.append("已下架！");

            BizException bizException = new BizException();
            bizException.setMessage(errorMessage.toString());
            throw bizException;
        }
        
        
        for (CartProductDto cartProductDto : cartProductDtoList) {
            @NotNull @Min(0) Long productId = cartProductDto.getProductId();
            Stock stock = stockMapper.selectStockForUpdate(productId);
            Item item = itemMapper.selectByPrimaryKey(productId);

            /*2、 ProductNum 不能超过 限购数量*/
            Long productNum = cartProductDto.getProductNum();
            if (stock.getRestrictCount() < productNum) {
                String errorMessage = "༼ つ ◕_◕ ༽つ，您购买的" + item.getTitle() + "数超过限购数量了！限购" + stock.getRestrictCount() + "个";
                ValidateException validateException = new ValidateException();
                validateException.setMessage(errorMessage);
                throw validateException;
            }


            // 3、购买的商品是否还有库存
            if (stock.getStockCount() < productNum) {
                String errorMessage = "来晚啦o(TヘTo)，您购买的" + item.getTitle() + "已经没有库存啦！";
                ValidateException validateException = new ValidateException();
                validateException.setMessage(errorMessage);
                throw validateException;
            }

        }
        return true;
    }
}
